package springcloud.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import springcloud.config.Result;
import springcloud.entity.MovieInfo;
import springcloud.mapper.MoiveInfoMapper;
import springcloud.service.IMoiveInfoService;
import springcloud.utils.BeanMapUtilByIntros;
import springcloud.utils.RedisUtil;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * @Author zhenyu
 * @desc
 * @Date 2022/10/14 11:36
 * @Version 1.0
 */
@Slf4j
@Primary
@Service
public class IMovieInfoServiceImpl extends ServiceImpl<MoiveInfoMapper, MovieInfo> implements IMoiveInfoService {

  @Autowired
  private RedisUtil redisUtil;
  @Autowired
  private RedisTemplate redisTemplate;

  /**
   * 初始化MySQL的数据到Redis
   */
  @Override
  @PostConstruct
  public void initInterfaceLimitsRedisCache() {

    //清除Redis的历史数据
    Set<String> keys = redisTemplate.keys("*");
    redisTemplate.delete(keys);

    log.info("清除Redis的历史数据完成...");

    List<MovieInfo> movieInfo = this.baseMapper.selectList(new QueryWrapper<MovieInfo>().gt("id", 0));

    for (MovieInfo info : movieInfo) {
      HashMap hashMap = new HashMap();
      hashMap.put("id", info.getId());
      hashMap.put("name", info.getName());
      hashMap.put("onlineDate", info.getOnlineDate());
      hashMap.put("state", info.getState());
      hashMap.put("offlineDate", info.getOfflineDate());
      hashMap.put("ticketNumber", info.getTicketNumber());
      hashMap.put("price", info.getPrice());
      redisUtil.hmset(String.valueOf(info.getId()), hashMap);
    }

    log.info("MySQL数据同步至Redis完成...");
  }

  /**
   * 今日电影列表查询
   *
   * @return
   */
  @Override
  public Result<?> getMoiveListToday() throws Exception {

    List<MovieInfo> movieList = getMovieInfos();

    return Result.success(movieList, "查询成功");
  }

  private List<MovieInfo> getMovieInfos() throws Exception {

    Set<String> keys = redisTemplate.keys("*");

    List<MovieInfo> movieList = new ArrayList<>();

    //redis存在缓存则使用缓存
    if (keys.size() > 0) {
      log.info("使用redis缓存开始查询...");
      for (String key : keys) {
        Map<Object, Object> hmget = redisUtil.hmget(key);
        //只取上线的
        if("1".equals(String.valueOf(hmget.get("state")))){
          MovieInfo movieInfo = BeanMapUtilByIntros.mapToBean(hmget, MovieInfo.class);
          movieList.add(movieInfo);
        }
      }
    } else {
      log.info("访问MySQL开始查询...");
      QueryWrapper queryWrapper = new QueryWrapper();
      queryWrapper.eq("state", 1);
      movieList = this.baseMapper.selectList(queryWrapper);
    }

    log.info("查询完成...");

    return movieList;
  }

  /**
   * 通过电影ID查询电影信息
   *
   * @param id 电影id
   * @return
   */
  @Override
  public MovieInfo getMoiveDetail(Integer id) {
    return this.getById(id);
  }

  /**
   * 成功购票后，更新余票数量
   *
   * @param id     电影id
   * @param number 购票数量
   * @return
   */
  @Override
  @Transactional(rollbackFor = RuntimeException.class)
  public Result<String> updateMovieNum(Integer id, Integer number) {
    try {
      MovieInfo movieInfo = new MovieInfo();
      movieInfo.setId(id);
      movieInfo.setTicketNumber(this.baseMapper.selectById(id).getTicketNumber() - number);
      this.baseMapper.updateById(movieInfo);
    } catch (Exception e) {
      return Result.fail(e.getMessage());
    }
    return Result.success("更新成功");
  }
}
